package cn.bbstone.e4.ui.log.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.eclipse.e4.core.services.events.IEventBroker;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.bbstone.e4.ui.log.event.LogPartEvents;
import cn.bbstone.e4.ui.log.logger.ILogConsole;
import cn.bbstone.e4.ui.log.logger.ILogOutputStream;
import cn.bbstone.e4.ui.log.service.LogsService;

@Component
public class LogsServiceImpl implements LogsService {

	private static final Logger log = LoggerFactory.getLogger(LogsServiceImpl.class);
	
	private static final String MSG_DELIMILTER = "\r\n";
	
	
	IEventBroker eventBroker;
	
	private ILogOutputStream logOutputStream;
	private ILogConsole logConsole;

	@Override
	public void setLogOutputStream(ILogOutputStream logOutputStream) {
		this.logOutputStream = logOutputStream;
	}

	@Override
	public void setLogConsole(ILogConsole logConsole) {
		this.logConsole = logConsole;
	}
	

	@Override
	public void setEventBroker(IEventBroker eventBroker) {
		this.eventBroker = eventBroker;
	}
	

	@Override
	public void printLog(String log) {
		if (log == null || log.trim().isEmpty()) return;
		
		writeOut(log);

//		for (int i = 0; i < 10; i++) {
//			try {
//				logOutputStream.write("Hello -> " + i + MSG_DELIMILTER);
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		}
	}

	private void writeOut(Object logMsg) {
		if (logOutputStream == null) {
			this.logOutputStream = logConsole.newOutputStream();
		}
		try {
			if (logMsg instanceof String) {
				String msg = String.valueOf(logMsg);
				logOutputStream.write(msg + MSG_DELIMILTER); // TODO test perform of this string join
			} 
			else if (logMsg instanceof byte[]) {
				byte[] msg = (byte[]) logMsg;
				byte[] result = append(msg, MSG_DELIMILTER.getBytes(Charset.forName("UTF-8")));
				logOutputStream.write(result);
			}
			// TODO support more log msg types
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private byte[] append(byte[] source, byte[] data) {
		byte[] result = new byte[source.length + data.length];
		// copy source byte[]
		System.arraycopy(source, 0, result, 0, source.length);
		// append data byte[]
		System.arraycopy(source, source.length, result, 0, data.length);
		return result;
	}
	
	public OutputStream getLogOutputStream() {
		return (OutputStream)logOutputStream;
	}

	@Override
	public void dispose() {
		logConsole.dispose();
		
	}
	

	@Override
	public void handleClearConsole() {
		log.info("invoked handleClearConsole method...");
	}

	@Override
	public void handleWordWrap() {
		eventBroker.post(LogPartEvents.WORD_WRAP, "click word-wrap button");
	}

	@Override
	public void handleLockConsole() {
		eventBroker.post(LogPartEvents.LOCK_CO, "click lock-co button");
	}

	

}
